/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package byzantine.controls;

import byzantine.controls.listeners.GeneralTypeListener;
import byzantine.ByzantineModel;
import byzantine.controls.listeners.AddGeneralListener;
import byzantine.controls.listeners.AttackCommandListener;
import byzantine.controls.listeners.ResetSimulationListener;
import byzantine.controls.listeners.RetreatCommandListener;
import byzantine.controls.listeners.StartSimulationListener;
import byzantine.views.View;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Image;
import java.awt.Toolkit;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;

/**
 *
 * @author rpathan
 */
public class SimulationSetupControls extends JPanel implements View {

    private static final String[] generalTypes = {ByzantineModel.COMMANDER, ByzantineModel.COMMANDER_REBEL,
        ByzantineModel.GENERAL, ByzantineModel.GENERAL_REBEL};
    //private int width;
    //private int height;
    //private int imageWidth;
    //private int imageHeight;
    //private int labelToComponentsSpacing;
    //private int imageToButtonSpacing;
    //private int buttonSpacing;
    private int width = 250;
    private int height = 360;
    private int imageWidth = 87;
    private int imageHeight = 137;
    private int labelToComponentsSpacing = 15;
    private int imageToButtonSpacing = 2;
    private int buttonSpacing = 8;
    private ByzantineModel model;
    private JLabel panelName;
    private JLabel imageLabel;
    private ImageIcon noTargetSelectedIcon;
    private ImageIcon commanderIcon;
    private ImageIcon commanderRebelIcon;
    private ImageIcon generalIcon;
    private ImageIcon generalRebelIcon;
    private JRadioButton attackButton;
    private JRadioButton retreatButton;
    private ButtonGroup buttonGroup;
    private JComboBox generalTypesBox;
    private JButton addButton;
    private JButton startButton;
    private JButton resetButton;
    private String selectedItem;

    public SimulationSetupControls(ByzantineModel model) {
        this.model = model;
        model.addObserver(this);
/*
        Toolkit t = Toolkit.getDefaultToolkit();
        Dimension screenSize = t.getScreenSize();
        width = (int)((screenSize.width - 10) * 0.25);
        height = (int)((screenSize.height - 100) * 0.55);
        imageWidth = (int)(width * 0.50);
        imageHeight = (int)(height * 0.55);
        labelToComponentsSpacing = (int)(height * 0.04);
        imageToButtonSpacing = (int)(height * 0.02);
        buttonSpacing = (int)(height * 0.02);
*/
        initializeControls();
    }

    private void initializeControls() {

        panelName = new JLabel("Simulation Setup");
        panelName.setAlignmentX(Component.CENTER_ALIGNMENT);
        panelName.setAlignmentY(Component.CENTER_ALIGNMENT);
        panelName.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 16));

        noTargetSelectedIcon = new ImageIcon(getClass().getResource("/byzantine/resources/NoTargetSelected.jpg"));
        Image noTargetSelectedScaled = noTargetSelectedIcon.getImage().getScaledInstance(imageWidth, imageHeight, Image.SCALE_SMOOTH);
        noTargetSelectedIcon.setImage(noTargetSelectedScaled);

        commanderIcon = new ImageIcon(getClass().getResource("/byzantine/resources/Commander.jpg"));
        Image commanderScaled = commanderIcon.getImage().getScaledInstance(imageWidth, imageHeight, Image.SCALE_SMOOTH);
        commanderIcon.setImage(commanderScaled);

        commanderRebelIcon = new ImageIcon(getClass().getResource("/byzantine/resources/Commander_Rebel.jpg"));
        Image commanderRebelScaled = commanderRebelIcon.getImage().getScaledInstance(imageWidth, imageHeight, Image.SCALE_SMOOTH);
        commanderRebelIcon.setImage(commanderRebelScaled);

        generalIcon = new ImageIcon(getClass().getResource("/byzantine/resources/General.jpg"));
        Image generalScaled = generalIcon.getImage().getScaledInstance(imageWidth, imageHeight, Image.SCALE_SMOOTH);
        generalIcon.setImage(generalScaled);

        generalRebelIcon = new ImageIcon(getClass().getResource("/byzantine/resources/General_Rebel.jpg"));
        Image generalRebelScaled = generalRebelIcon.getImage().getScaledInstance(imageWidth, imageHeight, Image.SCALE_SMOOTH);
        generalRebelIcon.setImage(generalRebelScaled);

        imageLabel = new JLabel(commanderIcon);
        imageLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
        imageLabel.setAlignmentY(Component.CENTER_ALIGNMENT);

        attackButton = new JRadioButton("Attack");
        attackButton.addActionListener(new AttackCommandListener(model));
        
        retreatButton = new JRadioButton("Retreat");
        retreatButton.addActionListener(new RetreatCommandListener(model));

        buttonGroup = new ButtonGroup();
        buttonGroup.add(attackButton);
        buttonGroup.add(retreatButton);

        attackButton.doClick();

        generalTypesBox = new JComboBox(generalTypes);
        generalTypesBox.setAlignmentX(Component.CENTER_ALIGNMENT);
        generalTypesBox.setAlignmentY(Component.CENTER_ALIGNMENT);
        generalTypesBox.addActionListener(new GeneralTypeListener(this));
        generalTypesBox.setSelectedItem(generalTypes[0]);
        generalTypesBox.setEnabled(true);

        selectedItem = generalTypesBox.getSelectedItem().toString();

        addButton = new JButton("Add");
        addButton.setAlignmentX(Component.CENTER_ALIGNMENT);
        addButton.setAlignmentY(Component.CENTER_ALIGNMENT);
        addButton.addActionListener(new AddGeneralListener(this, model));
        addButton.setEnabled(true);

        startButton = new JButton("Start Simulation");
        startButton.setAlignmentX(Component.CENTER_ALIGNMENT);
        startButton.setAlignmentY(Component.CENTER_ALIGNMENT);
        startButton.addActionListener(new StartSimulationListener(model));
        startButton.setEnabled(false);

        resetButton = new JButton("Reset Simulation");
        resetButton.setAlignmentX(Component.CENTER_ALIGNMENT);
        resetButton.setAlignmentY(Component.CENTER_ALIGNMENT);
        resetButton.addActionListener(new ResetSimulationListener(model));
        resetButton.setEnabled(true);

        Box box = Box.createVerticalBox();
        box.add(panelName);
        box.add(Box.createVerticalStrut(labelToComponentsSpacing));
        box.add(imageLabel);
        box.add(Box.createVerticalStrut(imageToButtonSpacing));
        Box box2 = Box.createHorizontalBox();
        box2.add(attackButton);
        box2.add(retreatButton);
        box.add(box2);
        box.add(Box.createVerticalStrut(buttonSpacing));
        box.add(generalTypesBox);
        box.add(Box.createVerticalStrut(buttonSpacing));
        box.add(addButton);
        box.add(Box.createVerticalStrut(buttonSpacing));
        box.add(startButton);
        box.add(Box.createVerticalStrut(buttonSpacing));
        box.add(resetButton);

        this.add(box);

        setBorder(BorderFactory.createEtchedBorder());
    }

    private void update() {

        if (model.isSimulationRunning() == false) {
            generalTypesBox.setEnabled(true);
            
        } else {
            generalTypesBox.setEnabled(false);
            
        }

        if (model.isSimulationRunning() == false && model.hasCommander() == false) {
            attackButton.setEnabled(true);
            retreatButton.setEnabled(true);
        } else {
            attackButton.setEnabled(false);
            retreatButton.setEnabled(false);
        }
        
        if (model.isSimulationRunning() == false
                && model.getNumGenerals() >= ByzantineModel.MIN_GENERALS_TO_RUN
                && model.hasCommander() == true) {
            startButton.setEnabled(true);
        } else {
            startButton.setEnabled(false);
        }

        if (model.hasCommanderStatusChanged() == true) {
            generalTypesBox.removeAllItems();
            if (model.hasCommander() == false) {
                for (int i = 0; i < generalTypes.length; i++) {
                    generalTypesBox.addItem(generalTypes[i]);
                }
            } else if (model.hasCommander() == true) {
                generalTypesBox.addItem(generalTypes[2]);
                generalTypesBox.addItem(generalTypes[3]);
            }
            generalTypesBox.setSelectedIndex(0);
            selectedItem = generalTypesBox.getSelectedItem().toString();
        }

        if (model.getNumGenerals() < ByzantineModel.MAX_GENERALS
                && model.isSimulationRunning() == false) {
            addButton.setEnabled(true);
        } else {
            addButton.setEnabled(false);
        }
    }

    public String getSelectedItem() {
        return selectedItem;
    }

    public void setSelectedItem(String generalType) {

        if (model.getAttackCommand()) {
            attackButton.setSelected(true);
        } else {
            retreatButton.setSelected(true);
        }

        selectedItem = generalType;

        if (generalType.equals(ByzantineModel.COMMANDER)) {
            imageLabel.setIcon(commanderIcon);
            imageLabel.setToolTipText(ByzantineModel.COMMANDER);
        } else if (generalType.equals(ByzantineModel.COMMANDER_REBEL)) {
            imageLabel.setIcon(commanderRebelIcon);
            imageLabel.setToolTipText(ByzantineModel.COMMANDER_REBEL);
        } else if (generalType.equals(ByzantineModel.GENERAL)) {
            imageLabel.setIcon(generalIcon);
            imageLabel.setToolTipText(ByzantineModel.GENERAL);
        } else if (generalType.equals(ByzantineModel.GENERAL_REBEL)) {
            imageLabel.setIcon(generalRebelIcon);
            imageLabel.setToolTipText(ByzantineModel.GENERAL_REBEL);
        }
    }

    public void valueChanged() {
        if (model.hasSimulationStatusChanged()
                || model.hasCommanderStatusChanged()
                || model.hasNumGeneralsChanged()
                || model.hasAttackCommandChanged()) {
            update();
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(width, height);
    }
}
